package com.github.jspxnet.worktask.dao.impl;

import com.github.jspxnet.boot.environment.Environment;
import com.github.jspxnet.enums.CongealEnumType;
import com.github.jspxnet.sioc.annotation.Bean;
import com.github.jspxnet.sioc.annotation.Ref;
import com.github.jspxnet.sober.criteria.expression.Expression;
import com.github.jspxnet.sober.jdbc.JdbcOperations;
import com.github.jspxnet.txweb.IMember;
import com.github.jspxnet.txweb.dao.TreeItemDAO;
import com.github.jspxnet.txweb.env.TXWebIoc;
import com.github.jspxnet.txweb.table.Member;
import com.github.jspxnet.txweb.table.MemberDept;
import com.github.jspxnet.txweb.table.TreeItem;
import com.github.jspxnet.txweb.util.MemberUtil;
import com.github.jspxnet.utils.ArrayUtil;
import com.github.jspxnet.utils.ObjectUtil;
import com.github.jspxnet.utils.StringUtil;
import com.github.jspxnet.worktask.dao.UserAdapterDAO;
import com.github.jspxnet.worktask.env.JWorkTask;
import com.github.jspxnet.worktask.table.ConfFlowNode;
import com.github.jspxnet.worktask.table.TaskAgency;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Bean(namespace = JWorkTask.namespace)
public class UserAdapterDAOImpl extends JdbcOperations implements UserAdapterDAO {
    @Ref(name = TXWebIoc.departmentDAO)
    protected TreeItemDAO departmentDAO;

    @Override
    public Member getMember(String userId)
    {
        return super.load(Member.class,userId);
    }

    /**
     * 判断当前节点是否用户有权限执行
     * @param userId 用户ID
     * @return 是否有权限
     */

    @Override
    public boolean isAuthority(ConfFlowNode confFlowNode, String userId)
    {
        if (confFlowNode==null)
        {
            return false;
        }
        if ("*".equals(confFlowNode.getUsers()))
        {
            return true;
        }

        Map<String, TaskAgency> taskAgencyMap = getTaskAgencyMap();
        List<Member> memberList = getMemberForExpression(confFlowNode.getUsers());
        for (Member member:memberList)
        {
            TaskAgency taskAgency = taskAgencyMap.get(userId);
            if (taskAgency==null)
            {
                continue;
            }
            member.setId(ObjectUtil.toLong(taskAgency.getAgencyUserId()));
            member.setName(taskAgency.getAgencyUserName());
            member.setCongealType(CongealEnumType.NO_CONGEAL.getValue());
        }
        return isInMemberList(memberList,userId);

    }


    private static boolean isInMemberList(List<Member> list,String userId)
    {
        if (ObjectUtil.isEmpty(list))
        {
            return false;
        }
        for (Member member:list)
        {
            if (member==null)
            {
                continue;
            }
            if (CongealEnumType.YES_CONGEAL.getValue()==member.getCongealType())
            {
                continue;
            }
            if (userId.equals(member.getId()+StringUtil.empty))
            {
                return true;
            }
        }
        return false;
    }


    @Override
    public Map<String,TaskAgency> getTaskAgencyMap()
    {
        List<TaskAgency> list =  createCriteria(TaskAgency.class).setCurrentPage(1).setTotalCount(100000).list(false);
        Map<String,TaskAgency> map = new HashMap<>();
        for (TaskAgency taskAgency:list)
        {
            map.put(taskAgency.getUserId(),taskAgency);
        }
        return map;
    }

    @Override
    public List<Member> getMemberForExpression(String select) {
        String[] lines = StringUtil.split(select, Environment.marker_split);
        List<Member> members = new ArrayList<>();
        if (ArrayUtil.isEmpty(lines)) {
            return members;
        }
        for (String line : lines) {
            if (MemberUtil.isUser(line)) {
                long id = StringUtil.toLong(StringUtil.trim(StringUtil.substringBetween(line, Environment.marker_user_startTag, Environment.marker_user_centerTag)));
                if (id <= 0) {
                    continue;
                }
                Member member = get(Member.class, id);
                if (member == null) {
                    continue;
                }
                members.add(member);
            }
            if (MemberUtil.isGroup(line)) {
                String department = StringUtil.trim(StringUtil.substringBetween(line, Environment.marker_group_startTag, Environment.marker_group_centerTag));
                if (StringUtil.isNull(department)) {
                    continue;
                }
                members.addAll(getDepartmentMember(department));
            }
        }
        return members;
    }



    /**
     * @param member      当前用户
     * @return 得到部门主管, 采用两种方式  1:直接通过pid 查找;2:通过部门树结构
     */
    @Override
    public List<Member> getDepartmentMember(IMember member) {
        List<Member> result = new ArrayList<>();
        if (member == null) {
            return result;
        }
        List<MemberDept> list = createCriteria(MemberDept.class).add(Expression.eq("uid", member.getId())).list(true);
        for (MemberDept memberDept : list) {
            result.addAll(getDepartmentMember(memberDept.getDepartmentId()));
        }
        return result;
    }

    /**
     * @param departmentId 部门ID
     * @return 得到部门主管, 采用两种方式  1:直接通过pid 查找;2:通过部门树结构
     */
    @Override
    public List<Member> getDepartmentMember(String departmentId) {
        List<Member> result = new ArrayList<>();
        TreeItem treeItem = departmentDAO.getTreeItem(departmentId);
        if (treeItem == null) {
            return result;
        }
        String manager = treeItem.getManager();
        if (StringUtil.isNull(manager)) {
            return result;
        }
        String[] uidArray = StringUtil.split(StringUtil.convertSemicolon(manager), StringUtil.SEMICOLON);
        for (String uidStr : uidArray) {
            if (!StringUtil.hasLength(uidStr)) {
                continue;
            }
            long uid;
            if (uidStr.contains(":")) {
                uid = StringUtil.toLong(StringUtil.getNumber(StringUtil.substringBetween(uidStr, "[", ":")));
            } else {
                uid = StringUtil.toLong(uidStr);
            }
            result.add(super.get(Member.class, uid, false));
        }
        return result;
    }

}
